﻿using ExcelDna.Integration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;

namespace ExcelUDF
{

    public partial class ExcelUDF
    {
        [ExcelFunction(Description = "在一个全路径下获取文件名，格式为：文件名+后缀名,如：C:\test\test.txt返回的是test.txt字符串")]
        public static string GetFileName(
    [ExcelArgument(Description = "传入一个含路径的文件全名字符串")] string srcFullpath)
        {
            return Path.GetFileName(srcFullpath);
        }

        [ExcelFunction(Description = "在一个全路径下获取文件名不含文件后缀名，如：C:\test\test.txt返回的是test字符串)")]
        public static string GetFileNameWithoutExtension(
                             [ExcelArgument(Description = "传入一个含路径的文件全名字符串")] string srcFullpath)
        {
            return Path.GetFileNameWithoutExtension(srcFullpath);
        }

        [ExcelFunction(Description = "文件全名或一个含文件名后缀的字符串获取文件后缀名，如：C:\test\test.txt返回的是.txt字符串)")]
        public static string GetExtension(
                             [ExcelArgument(Description = "传入一个含路径的文件全名或一个含文件名后缀的字符串")] string srcFullpath)
        {
            return Path.GetExtension(srcFullpath);
        }


        [ExcelFunction(Description = "获取指定目录下的子文件夹,srcFolder为传入的顶层目录，containsText可用作筛选包含containsText内容的文件夹，isSearchAllDirectory为是否查找顶层目录下的文件夹的所有子文件夹")]
        public static object GetSubFolders(
            [ExcelArgument(Description = "传入的顶层目录，最终返回的结果将是此目录下的文件夹或子文件夹")] string srcFolder,
            [ExcelArgument(Description = "查找的文件夹中是否需要包含指定字符串，不传参数默认为返回所有文件夹，可传入复杂的正则表达式匹配。")] string optContainsText,
            [ExcelArgument(Description = "是否查找顶层目录下的文件夹的所有子文件夹，TRUE和非0的字符或数字为搜索子文件夹，其他为否，不传参数时默认为否")] object optIsSearchAllDirectory,
            [ExcelArgument(Description = "返回的结果是按按列排列还是按行排列，传入L按列排列，传入H按行排列，不传参数或传入非L或H则默认按列排列")] string optAlignHorL)
        {

            string[] subfolders;
            if (Common.IsMissOrEmpty(optContainsText))
            {
                optContainsText = string.Empty;
            }
            //当isSearchAllDirectory为空或false，默认为只搜索顶层文件夹
            if (Common.IsMissOrEmpty(optIsSearchAllDirectory) || Common.TransBoolPara(optIsSearchAllDirectory) == false)
            {
                subfolders = Directory.EnumerateDirectories(srcFolder).Where(s => isContainsText(s, optContainsText)).ToArray();
            }
            else
            {

                subfolders = Directory.EnumerateDirectories(srcFolder, "*", SearchOption.AllDirectories).Where(s => isContainsText(s, optContainsText)).ToArray();
            }

            return Common.ReturnDataArray(subfolders,optAlignHorL);

        }

 

        public static object GetFiles(
                [ExcelArgument(Description = "传入的顶层目录，最终返回的结果将是此目录下的文件夹或子文件夹下的全路径文件名")] string srcFolder,
                [ExcelArgument(Description = "查找的全路径文件名中是否需要包含指定字符串，不传参数默认为返回所有文件夹，可传入复杂的正则表达式匹配。")] string containsText,
                [ExcelArgument(Description = "是否查找顶层目录下的文件夹的所有子文件夹，TRUE和非0的字符或数字为搜索子文件夹，其他为否，不传参数时默认为否")] object isSearchAllDirectory,
                [ExcelArgument(Description = "返回的结果是按按列排列还是按行排列，传入L按列排列，传入H按行排列，不传参数或传入非L或H则默认按列排列")] string optAlignHorL)
        {
            string[] files;
            if (Common.IsMissOrEmpty(containsText))
            {
                containsText = string.Empty;
            }
            //当isSearchAllDirectory为空或false，默认为只搜索顶层文件夹
            if (Common.IsMissOrEmpty(isSearchAllDirectory) ||Common.TransBoolPara(isSearchAllDirectory) == false)
            {
                files = Directory.EnumerateFiles(srcFolder).Where(s => isContainsText(s, containsText)).ToArray();
            }
            else
            {

                files = Directory.EnumerateFiles(srcFolder, "*", SearchOption.AllDirectories).Where(s => isContainsText(s, containsText)).ToArray();
            }

            return Common.ReturnDataArray(files, optAlignHorL);
        }



        [ExcelFunction(Description = "获取指定目录下的不同层级的文件夹名称。")]
        public static string GetFolderByDepth(
    [ExcelArgument(Description = "传入一个文件夹的详细路径")] string srcFolder,
    [ExcelArgument(Description = "文件夹深度，请传入整数，若是小数将截断，正数为从左到右查，负数为从右往左查,不传参数时默认为右边第1层文件夹")] int intFolderDepth
            )
        {

            List<string> listFolders = srcFolder.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries).ToList();

            if (Common.IsMissOrEmpty(intFolderDepth))
            { intFolderDepth = -1; }

            if (Common.TransNumberPara(intFolderDepth) < 0)
            {
                listFolders.Reverse();
            }

            if (Common.TransNumberPara(intFolderDepth) == 0)
            {
                return string.Empty;
            }
            //当有文件扩展名，路径为文件全路径，非文件夹全路径
            else if (Path.HasExtension(srcFolder))
            {
                return listFolders[(int)Math.Abs(Common.TransNumberPara(intFolderDepth))];
            }
            else
            {
                return listFolders[(int)Math.Abs(Common.TransNumberPara(intFolderDepth)) - 1];
            }

        }



        private static bool isContainsText(string s, string containstext)
        {
            if (string.IsNullOrEmpty(containstext))
            {
                return true;
            }
            else
            {
                return Regex.IsMatch(s, containstext);
            }

        }

    }
}
